/**************************************************************************************
*  SPI.c
*
*  This file defines all native methods that have to be implemented to support
*  the class lpc2xxx/comm/SPI
*
*  Application developer should use the following functions to get access to
*  arrays and String object:
*       vmGetStringCount
*       vmGetStringArray
*       vmGetArraySize
*       vmGetArray
*  These functions are accessible via vm_config_t structure.
*
*  Native methods implementation
*  -----------------------------
*  Note that if the native method is NOT declared as static then param[0]
*  contains object's reference and must be skiped when accessing the native
*  method parameters.
**************************************************************************************
*
* This file is covered by the GNU GPL with the following exception:
*   As a special exception, the copyright holders of this library give you permission
*   to link this library with independent modules to produce an executable, regardless
*   of the license terms of these independent modules, and to copy and distribute the
*   resulting executable under terms of your choice, provided that you also meet, for
*   each linked independent module, the terms and conditions of the license of that
*   module. An independent module is a module which is not derived from or based on
*   this library. If you modify this library, you may extend this exception to your
*   version of the library, but you are not obligated to do so. If you do not wish
*   to do so, delete this exception statement from your version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Copyright (c) 2000-2006 RTJ Computing Pty. Ltd. All rights reserved.
**************************************************************************************/
#include <lpc2xxx.h>
#include "spi.h"
#include "javavm.h"

extern vm_config_t vmconfig;


/****************************************************************************
* Initialises the SPI
* On entry: param[0] - pin that will be  used to activate the chip select signal of slave device.
*
* Java prototype:
*   public static native void init(int csPin);
*
****************************************************************************/
int16 lpc2xxx_comm_SPI_init(int32 param[], int32 *retval)
{
    // remember SPI slave CS pin
    spiCmd.cs = param[0];
    
    // connect SPI bus to IO-pins
    PINSEL0 |= 0x00005500;

    // initialize SPI interface
    SPI_SPCCR = 0x08;    
    SPI_SPCR  = 0x60 | 0x80;   //0x80 = enable interrupts from spi

    // make SPI slave chip select an output and set signal high
    IODIR |= spiCmd.cs;
    IOSET = spiCmd.cs;

    //initialize VIC for SPI interrupts
    VICIntSelect  &= ~0x00000400;     // SPI interrupt is assigned to IRQ (not FIQ)
    VICVectAddr10  = (tU32)spiISR;    // register ISR address
    VICVectCntl10  = 0x2A;            // enable vector interrupt for SPI
    VICIntEnable   = 0x00000400;      // enable SPI interrupt

    return NO_EXCEP;
}

/****************************************************************************
* Read/Write command for transferring data from/to slave SPI device.
* On entry: param[0] - READ/WRITE command identifier
*           param[1] - source/destination byte array
*           param[2] - offset to byte array
*           param[3] - number of bytes to transfer
*
* Java prototype:
*   private static native void command(int cmd, byte[] arr, int offs, int len);
*
****************************************************************************/
int16 lpc2xxx_comm_SPI_command(int32 param[], int32 *retval)
{
    uint32 arrSize;
    uint8 *arr;

    arrSize = vmconfig.vmGetArraySize(param[1]);
    arr = (uint8 *)vmconfig.vmGetArray(param[1]);
    if (arr == NULL)
        return EXCEP_NullPointer;

    if (param[2] + param[3] > arrSize) 
        return EXCEP_IndexOutOfBounds;

    spiCmd.cmd = param[0];
    spiCmd.len = param[3];
    spiCmd.buf = arr + param[2];
    spiCmd.ready = FALSE;

    // activate SPI slave
    IOCLR0 = spiCmd.cs;  

    // start transmission with first byte
    if (spiCmd.cmd == SPI_COMMAND_WRITE)
        SPI_SPDR = *spiCmd.buf;
    else 
        SPI_SPDR = 0xFF;

    return NO_EXCEP;
}

/****************************************************************************
* Checks if the SPI is ready to accept a new command.
* On entry: n/a
* On return: retval=true if SPI is ready for a new command.
*
* Java prototype:
*   public static native boolean ready();
*
****************************************************************************/
int16 lpc2xxx_comm_SPI_ready(int32 param[], int32 *retval)
{
    *retval = spiCmd.ready;

    return NO_EXCEP;
}

